package com.io.commonlink.mqtt

import android.content.Context
import android.net.ConnectivityManager
import android.os.Handler
import android.provider.Settings
import com.io.commonlib.enum.NetworkType
import com.io.commonlib.helper.CommonDeviceHelper
import com.io.commonlib.helper.EncryptHelper
import com.io.commonlib.helper.LogHelper
import kotlinx.coroutines.*
import org.eclipse.paho.android.service.MqttAndroidClient
import org.eclipse.paho.client.mqttv3.*

/**
 * Description:
 * 2020-07-31 9:12
 * @author LiuMin
 */
class MQTTManager(
    context: Context,
    mqttUrl: String,
    clientId: String,
    instanceId: String,
    accessKey: String,
    secretKey: String
) {
    private val TAG = MQTTManager::class.java.simpleName
    private var mqttUrl = ""
    private var mqttAndroidClient: MqttAndroidClient? = null
    private var clientId = ""
    private var instanceId = ""
    private var accessKey = ""
    private var secretKey = ""
    private var myContext: Context
    private var mqttConnectOptions: MqttConnectOptions? = null
    private var mqttActionListener: IMqttActionListener? = null
    private val handler = Handler()
    private lateinit var job:Job
    private lateinit var scope: CoroutineScope

    //private val connectTask = Runnable { connectMqtt() }

    init {
        this.mqttUrl = mqttUrl
        this.clientId = clientId
        this.instanceId = instanceId
        this.accessKey = accessKey
        this.secretKey = secretKey
        myContext = context
        job = Job()
        scope = CoroutineScope(job)
    }

    /**
     * 初始化
     */
    fun initMqtt() {
        mqttAndroidClient = MqttAndroidClient(myContext, mqttUrl, clientId)
        mqttConnectOptions = MqttConnectOptions()
        try {
            mqttConnectOptions?.let {
                it.connectionTimeout = 5000
                it.keepAliveInterval = 90
                it.isAutomaticReconnect = true
                it.isCleanSession = false //如果是true，则会导致离线切换到在线的时候收不到消息
                // Signature 方式
                it.userName = "Signature|$accessKey|$instanceId"
                it.password = EncryptHelper.encryptSHA(
                    clientId,
                    secretKey
                ).toCharArray()
            }

            /**
             * Token方式
             * mqttConnectOptions.setUserName("Token|" + Config.accessKey + "|" + Config.instanceId);
             * mqttConnectOptions.setPassword("RW|xxx");
             */
        } catch (e: Exception) {
            LogHelper.e(TAG, e.message!!)
        }
    }

    /**
     * 设置mqtt回调
     * @param callback
     */
    fun setMqttCallback(callback: MqttCallbackExtended?) {
        mqttAndroidClient?.setCallback(callback)
    }

    fun setMqttActionListener(listener: IMqttActionListener?){
        mqttActionListener = listener
    }

    /**
     * 订阅消息
     */
    fun subscribeToTopic(
        topicFilter: Array<String>,
        qosArray: IntArray
    ) {
        try {
            if (mqttAndroidClient?.isConnected == true) {
                mqttAndroidClient?.subscribe(
                    topicFilter,
                    qosArray,
                    null,
                    object : IMqttActionListener {
                        override fun onSuccess(asyncActionToken: IMqttToken) {
                            LogHelper.d(TAG, "subscribe---onSuccess")
                        }

                        override fun onFailure(
                            asyncActionToken: IMqttToken,
                            exception: Throwable
                        ) {
                            LogHelper.d(TAG, "subscribe---onFailure")
                        }
                    })
            } else {
                LogHelper.d(
                    TAG, "subscribeToTopic-->mqttAndroidClient为空吗？"
                            + (mqttAndroidClient == null)
                )
            }
        } catch (ex: MqttException) {
            if (ex != null) {
                LogHelper.e(TAG, "subscribe:exception-->" + ex.message)
            }
        }
    }

    /**
     * 订阅消息
     */
    fun subscribeToTopic(
        topicFilter: String,
        qosArray: Int
    ) {
        try {
            if (mqttAndroidClient?.isConnected == true) {
                mqttAndroidClient?.subscribe(
                    topicFilter,
                    qosArray,
                    null,
                    object : IMqttActionListener {
                        override fun onSuccess(asyncActionToken: IMqttToken) {
                            LogHelper.d(TAG, "subscribe---onSuccess")
                        }

                        override fun onFailure(
                            asyncActionToken: IMqttToken,
                            exception: Throwable
                        ) {
                            LogHelper.d(TAG, "subscribe---onFailure")
                        }
                    })
            } else {
                LogHelper.d(
                    TAG, "subscribeToTopic-->mqttAndroidClient为空吗？"
                            + (mqttAndroidClient == null)
                )
            }
        } catch (ex: MqttException) {
            if (ex != null) {
                LogHelper.e(TAG, "subscribe:exception-->" + ex.message)
            }
        }
    }

    fun unsubscribe(topics: Array<String?>?) {
        try {
            mqttAndroidClient?.unsubscribe(topics, myContext, mqttActionListener)
        } catch (e: MqttException) {
            if (e != null) {
                LogHelper.e(TAG, "subscribe:exception-->" + e.message)
            }
        }
    }

    fun unsubscribe(topic: String) {
        try {
            LogHelper.d(TAG, "取消订阅消息----$topic")
            mqttAndroidClient?.unsubscribe(topic, myContext, mqttActionListener)
        } catch (e: MqttException) {
            if (e != null) {
                LogHelper.e(TAG, "subscribe:exception-->" + e.message)
            }
        }
    }

    /**
     * 连接mqtt
     */
    fun connectMqtt() {
        scope.launch(Dispatchers.Default) {
            connect()
        }
    }

    private suspend fun connect(){
        val isNetworkOk = CommonDeviceHelper().pingWeb("www.baidu.com", 1)
        if (mqttAndroidClient?.isConnected == false && isNetworkOk) {
            try {
                mqttAndroidClient?.connect(mqttConnectOptions, null, mqttActionListener)
            } catch (e: MqttException) {
                LogHelper.e(TAG, "connectMqtt" + e.message)
            }
        } else {
            delay(5*1000)
            connect()
        }
    }

    /**
     * mqtt断开连接
     */
    fun disconnectMqtt() {
        try {
            if (mqttAndroidClient?.isConnected == true) {
                mqttAndroidClient?.disconnect(null, mqttActionListener)
            }
            scope.cancel()
        } catch (e: MqttException) {
            LogHelper.e(TAG, "disconnectMqtt  MqttException-->" + e.message)
        }
    }

    /**
     * 发布消息
     */
    fun publishMessage(topic: String?, content: String) {
        try {
            val message = MqttMessage()
            message.payload = content.toByteArray()
            mqttAndroidClient?.publish(topic, message, null, mqttActionListener)
        } catch (e: MqttException) {
            LogHelper.e(TAG, "publishMessage  MqttException-->" + e.message)
        }
    }

    /**
     * 关闭mqttAndroidClient的连接，取消注册的消息
     */
    fun destroy() {
        try {
            if (mqttAndroidClient != null) {
                mqttAndroidClient?.disconnect()
                mqttAndroidClient?.unregisterResources()
            }
        } catch (e: MqttException) {
            LogHelper.e(TAG, "destroy--" + e.message)
        }
    }
    //endregion

}